home *** CD-ROM | disk | FTP | other *** search
- /* Routinen für IFF ILBM-Dateien
- ** File: spiff.c
- */
-
-
- /* Unterroutine zum Test auf FORM ILBM, RGBN und RGB8 */
-
-
- BYTE IsIFF(struct IFFHandle *iff)
- {
- LONG error = NULL;
- struct ContextNode *top = NULL;
-
- if(!(error=ParseIFF(iff,IFFPARSE_RAWSTEP)))
- {
-
- if(top=CurrentChunk(iff))
- {
-
- if((top->cn_Type) == ID_ILBM) return(1L);
- if((top->cn_Type) == MAKE_ID('R','G','B','N')) return(2L);
- if((top->cn_Type) == MAKE_ID('R','G','B','8')) return(3L);
- }
- }
- else
- {
- if(error != -10L) OutText(localstr[MSG_EPARSEIFF]);
- }
-
- return(NULL);
- }
-
-
- /* Einlesen des BMHD Chunk in die Struktur */
-
-
- BOOL GetBMHD(struct IFFHandle *iff,BitMapHeader *bmap)
- {
- if(ReadChunkBytes(iff,bmap,20L) == 20L) return(TRUE);
- return(FALSE);
- }
-
-
- /* Einlesen des CAMG Chunk */
-
-
- BOOL GetCAMG(struct IFFHandle *iff,ULONG *mode)
- {
- if(ReadChunkBytes(iff,mode,4L) == 4L) return(TRUE);
- return(FALSE);
- }
-
-
- /* Einlesen des CMAP Chunk in ColorRegister */
-
-
- BOOL GetCMAP(struct IFFHandle *iff,UBYTE *creg,LONG cnum)
- {
- if(ReadChunkBytes(iff,creg,3*cnum) == 3*cnum) return(TRUE);
- return(FALSE);
- }
-
-
- /* Einlesen des BODY Chunk aus einer IFF ILBM Datei */
-
-
- LONG GetBODY_ILBM(struct IFFHandle *iff,BitMapHeader *bmap,ULONG mode,struct Screen *scr)
- {
- UWORD width = scr->Width; /* screen width */
- UWORD height = scr->Height; /* screen height */
-
- LONG ok = TRUE;
- LONG actual = NULL;
- LONG bcount;
- UWORD bpline; /* Anzahl der Bytes in einer Zeile */
- LONG pixoffset = NULL;
- UWORD wpline; /* Anzahl der Words in einer Zeile */
- WORD gfxmode = NULL;
- register WORD min128=-128;
- register LONG srcbytes,dstbytes;
- register BYTE *source;
- register BYTE *dest;
- register BYTE *scrbase;
- register UWORD *sbuf = NULL; /* Buffer für eine Bildzeile */
- register UBYTE *hambuf = NULL; /* Buffer für eine HAM Bildzeile */
- register WORD c,h,p,n;
-
- gfxmode = 8;
-
- if(mode & HAM_KEY)
- {
- if(bmap->nPlanes == 6) gfxmode = 12;
- if(bmap->nPlanes == 8) gfxmode = 23;
- }
-
- if(USERFLGS & PFLG_TRUECLR)
- {
- gfxmode = 24;
- if(USERFLGS & PFLG_TC15BIT) gfxmode = 15;
- if(USERFLGS & PFLG_TC16BIT) gfxmode = 16;
- }
-
- bpline = (ULONG)(bmap->w / 8);
- if(((LONG)bmap->w) % 8) bpline++;
- if(((LONG)bpline) % 2) bpline++;
-
- bcount = (bmap->nPlanes) * bpline;
- wpline = bpline / 2;
-
- scrbase = LockVillageScreen(scr);
-
- if(!(USERFLGS & UFLG_NOCENTER)) /* Zentrierung des Bildes auf dem Screen */
- {
- switch(gfxmode)
- {
- case 8:
-
- scrbase += (((height) - (bmap->h)) / 2 * (width)) + (((width) - (bmap->w)) / 2);
- break;
-
- case 12:
- case 15:
- case 16:
-
- scrbase += (((height) - (bmap->h)) / 2 * (width) * 2) + (((width) - (bmap->w)) / 2 * 2);
- break;
-
- case 23:
- case 24:
-
- scrbase += (((height) - (bmap->h)) / 2 * (width) * 3) + (((width) - (bmap->w)) / 2 * 3);
- break;
- }
- }
-
- if(sbuf = AllocVec((ULONG)(bpline*(UWORD)bmap->nPlanes),MEMF_PUBLIC|MEMF_CLEAR))
- {
-
- if(mode & HAM_KEY)
- {
- if(!(hambuf = AllocVec((ULONG)bmap->w,MEMF_PUBLIC|MEMF_CLEAR)))
- {
- ok = FALSE;
- goto ByteError;
- }
- }
-
- if(bmap->compression)
- {
- srcbytes = ReadChunkBytes(iff,cbuf,cbufsize); /* Lesen der Daten nach cbuf */
- source = cbuf;
- }
-
- for(h=0; h < (bmap->h); h++)
- {
-
- if(bmap->compression)
- {
- dest = (BYTE *)sbuf;
-
- for(p=0; p < (bmap->nPlanes); p++)
- {
- dstbytes = bpline;
-
- while(dstbytes > 0)
- {
-
- if((srcbytes -= 1) < 0)
- {
-
- if((srcbytes = ReadChunkBytes(iff,cbuf,cbufsize) - 1) < 0)
- {
- ok = FALSE;
- goto ByteError;
- }
- source = cbuf;
- }
-
- n = *source++;
-
- if(n >= 0)
- {
- n += 1;
-
- if((srcbytes -= n) < 0)
- {
- srcbytes += n;
-
- for(c=0; c < srcbytes; c++) cbuf[c] = *source++;
-
- if(ReadChunkBytes(iff,&cbuf[srcbytes],cbufsize - srcbytes) < 0)
- {
- ok = FALSE;
- goto ByteError;
- }
- srcbytes = cbufsize-n;
- source = cbuf;
- }
-
- if((dstbytes -= n) < 0) break;
- do (*dest++ = *source++); while(--n > 0);
- }
-
- else if(n != min128)
- {
- n = -n + 1;
-
- if((srcbytes -= 1) < 0)
- {
-
- if((srcbytes = ReadChunkBytes(iff,cbuf,cbufsize) - 1) < 0)
- {
- ok = FALSE;
- goto ByteError;
- }
- source = cbuf;
- }
-
- if((dstbytes -= n) < 0) break;
- c = *source++;
- do *dest++ = c; while(--n > 0);
- }
- }
- }
- }
- else actual = ReadChunkBytes(iff,sbuf,bcount);
-
- switch(gfxmode)
- {
- case 8:
-
- Convert8(&scrbase[pixoffset],sbuf,bmap->nPlanes,bpline);
- pixoffset += width;
- break;
-
- case 12:
-
- ConvertHAM6(&scrbase[pixoffset],sbuf,hambuf,color,bpline);
- pixoffset += width*2;
- break;
-
-
- case 15:
-
- Convert15(&scrbase[pixoffset],sbuf,bpline);
- pixoffset += width*2;
- break;
-
- case 16:
-
- Convert16(&scrbase[pixoffset],sbuf,bpline);
- pixoffset += width*2;
- break;
-
- case 23:
-
- ConvertHAM8(&scrbase[pixoffset],sbuf,hambuf,color,bpline);
- pixoffset += width*3;
- break;
-
- case 24:
-
- Convert24(&scrbase[pixoffset],sbuf,bpline);
- pixoffset += width*3;
- break;
-
- }
- }
-
- ByteError:
-
- if(hambuf) FreeVec(hambuf);
- FreeVec(sbuf);
- }
-
- UnLockVillageScreen(scr);
-
- return(ok);
- }
-
-
- /* Einlesen des BODY Chunk aus einer IFF RGBN bzw. RGB8 Datei */
-
- LONG GetBODY_RGBx(struct IFFHandle *iff,BitMapHeader *bmap,struct Screen *scr)
- {
- UWORD width = scr->Width;
- UWORD height = scr->Height;
-
- LONG ok = TRUE;
- LONG pixoffset=NULL;
- WORD gfxmode=NULL;
- register LONG srcbytes,dstbytes;
- register UBYTE *source;
- register UBYTE *dest;
- register UBYTE *scrbase;
- register WORD c,h;
-
- UBYTE red,green,blue;
- register UWORD repeat = NULL;
-
- gfxmode = 12;
-
- if(USERFLGS & PFLG_TRUECLR)
- {
- gfxmode = 24;
- if(USERFLGS & PFLG_TC15BIT) gfxmode = 15;
- if(USERFLGS & PFLG_TC16BIT) gfxmode = 16;
- }
-
- scrbase = LockVillageScreen(s);
-
- if(!(USERFLGS & UFLG_NOCENTER))
- {
- switch(gfxmode)
- {
- case 12:
- case 15:
- case 16:
-
- scrbase += (((height) - (bmap->h)) / 2 * (width) * 2) + (((width) - (bmap->w)) / 2 * 2);
- break;
-
- case 24:
-
- scrbase += (((height) - (bmap->h)) / 2 * (width) * 3) + (((width) - (bmap->w)) / 2 * 3);
- break;
- }
- }
-
- srcbytes = ReadChunkBytes(iff,cbuf,cbufsize); /* Lesen der Daten nach cbuf */
- source = cbuf;
-
- if(gfxmode != 12)
- {
-
- for(h=0; h < (bmap->h); h++)
- {
- dest = &scrbase[pixoffset];
-
- dstbytes = bmap->w;
-
- while(dstbytes > 0)
- {
-
- if(!repeat) /* 1) Wdh.zähler kann über eine Zeile hinaus reichen */
- {
-
- if((srcbytes -= 4) < 0)
- {
- srcbytes += 4;
-
- for(c=0; c < srcbytes; c++) cbuf[c] = *source++;
-
- if(ReadChunkBytes(iff,&cbuf[srcbytes],cbufsize - srcbytes) < 0)
- {
- ok = FALSE;
- goto RGBxError;
- }
- srcbytes = cbufsize-4;
- source = cbuf;
- }
-
- red = *source++;
- green = *source++;
- blue = *source++;
- repeat = (UWORD)(*source++ & 0x007f);
-
- if(!repeat)
- {
-
- if((srcbytes -= 1) < 0)
- {
-
- if(ReadChunkBytes(iff,cbuf,cbufsize) < 0)
- {
- ok = FALSE;
- goto RGBxError;
- }
- srcbytes = cbufsize - 1;
- source = cbuf;
- }
-
- if(!(repeat = (UWORD)(*source++)))
- {
-
- if((srcbytes -= 2) < 0)
- {
- srcbytes += 2;
-
- for(c=0; c < srcbytes; c++) cbuf[c] = *source++;
-
- if(ReadChunkBytes(iff,&cbuf[srcbytes],cbufsize - srcbytes) < 0)
- {
- ok = FALSE;
- goto RGBxError;
- }
- srcbytes = cbufsize-2;
- source = cbuf;
- }
-
- repeat = (UWORD)((*source++)<<8);
- repeat += (UWORD)*source++;
- }
- }
- }
-
- if((dstbytes -= repeat) < 0) repeat += dstbytes; /* siehe 1) */
-
- do
- {
- switch(gfxmode)
- {
- case 15:
-
- *dest++ = ((green<<2)&0xE0) | ((blue>>3)&0x1F);
- *dest++ = ((green>>6)&0x03) | ((red>>1)&0x7C);
- break;
-
- case 16:
-
- *dest++ = ((green<<3)&0xE0) | ((blue>>3)&0x1F);
- *dest++ = ((green>>5)&0x07) | (red&0xF8);
- break;
-
- case 24:
-
- *dest++ = blue;
- *dest++ = green;
- *dest++ = red;
- break;
- }
- } while(--repeat > 0);
-
- if(dstbytes < 0) /* siehe 1) */
- {
- repeat = -dstbytes;
- break;
- }
-
- }
- switch(gfxmode)
- {
- case 15:
- case 16:
- pixoffset += width * 2;
- break;
-
- case 24:
- pixoffset += width * 3;
- break;
- }
- }
- }
- else
- {
-
- for(h=0; h < (bmap->h); h++)
- {
- dest = &scrbase[pixoffset];
-
- dstbytes = (LONG)bmap->w;
-
- while(dstbytes > 0)
- {
-
- if(!repeat) /* 1) Wdh.zähler kann über eine Zeile hinaus reichen */
- {
-
- if((srcbytes -= 2) < 0)
- {
- srcbytes += 2;
-
- for(c=0; c < srcbytes; c++) cbuf[c] = *source++;
-
- if(ReadChunkBytes(iff,&cbuf[srcbytes],cbufsize - srcbytes) < 0)
- {
- ok = FALSE;
- goto RGBxError;
- }
- srcbytes = cbufsize - 2;
- source = cbuf;
- }
-
- red = *source & 0xf0;
- green = (*source++<<4) & 0xf0;
- blue = *source & 0xf0;
- repeat = (UWORD)(*source++ & 0x07);
-
- if(!repeat)
- {
-
- if((srcbytes -= 1) < 0)
- {
-
- if(ReadChunkBytes(iff,cbuf,cbufsize) < 0)
- {
- ok = FALSE;
- goto RGBxError;
- }
- srcbytes = cbufsize - 1;
- source = cbuf;
- }
-
- if(!(repeat = (UWORD)(*source++)))
- {
-
- if((srcbytes -= 2) < 0)
- {
- srcbytes += 2;
-
- for(c=0; c < srcbytes; c++) cbuf[c] = *source++;
-
- if(ReadChunkBytes(iff,&cbuf[srcbytes],cbufsize - srcbytes) < 0)
- {
- ok = FALSE;
- goto RGBxError;
- }
- srcbytes = cbufsize - 2;
- source = cbuf;
- }
-
- repeat = (UWORD)((*source++)<<8);
- repeat += (UWORD)*source++;
- }
- }
- }
-
- if((dstbytes -= repeat) < 0) repeat += dstbytes; /* siehe 1) */
-
- do
- {
- *dest++ = ((green<<2)&0xE0) | ((blue>>3)&0x1F);
- *dest++ = ((green>>6)&0x03) | ((red>>1)&0x7C);
- } while(--repeat > 0);
-
- if(dstbytes < 0) /* siehe 1) */
- {
- repeat = -dstbytes;
- break;
- }
-
- }
- pixoffset += width * 2;
- }
- }
-
- RGBxError:
-
- UnLockVillageScreen(s);
-
- return(ok);
- }
-